package com.flycat.service.impl;

import com.flycat.common.constants.Constants;
import com.flycat.common.enumeration.*;
import com.flycat.common.util.DateUtils;
import com.flycat.common.util.JsonUtils;
import com.flycat.common.util.OrderIdUtils;
import com.flycat.core.AbstractService;
import com.flycat.core.Result;
import com.flycat.core.ResultGenerator;
import com.flycat.dao.po.OrderDetail;
import com.flycat.dao.po.OrderDynamicDetail;
import com.flycat.dao.po.PriceStrategy;
import com.flycat.dao.po.ProductCar;
import com.flycat.dto.*;
import com.flycat.dto.query.OrderDetailQuery;
import com.flycat.service.OrderDetailService;
import com.flycat.service.OrderDynamicDetailService;
import com.flycat.service.PriceStrategyService;
import com.flycat.service.ProductCarService;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * Created by yalei.chen on 2017/09/16.
 */
@Service
@Transactional
public class AdminOrderDetailServiceImpl extends AbstractService<OrderDetail> implements OrderDetailService {

    private static final Logger logger = LoggerFactory.getLogger(AdminOrderDetailServiceImpl.class);

    @Resource
    private ProductCarService productCarService;

    @Resource
    private OrderDynamicDetailService orderDynamicDetailService;

    @Resource
    private PriceStrategyService priceStrategyService;

    @Override
    public List<SupplierCarOrder> queryOrderAdmin(OrderDetailQuery orderDetailQuery) {

        logger.info("查询订单列表 req:{}", JsonUtils.toJson(orderDetailQuery));
        if (orderDetailQuery == null) {
            return Lists.newArrayList();
        }
        PageHelper.startPage(orderDetailQuery.getPageNo(), orderDetailQuery.getPageSize());
        Condition condition = new Condition(OrderDetail.class);
        Example.Criteria criteria = condition.createCriteria();
        buildCondition(criteria,orderDetailQuery);
        List<OrderDetail> list = findByCondition(condition);
        List<SupplierCarOrder> carOrders = list.stream().map(item->{
            SupplierCarOrder carOrder = new SupplierCarOrder();
            carOrder.setProductTypeName(TypeEnum.getEnum(item.getType()).msg);
            carOrder.setUserNme(item.getUserName());
            carOrder.setOrderStatus(Integer.valueOf(item.getStatus()));
            carOrder.setOrderTime(item.getOrderTime());
            carOrder.setCityName(item.getOrderCity());
            carOrder.setServiceType(ServiceTypeEnum.getEnum(String.valueOf(item.getOrderType())).msg);
            carOrder.setOrderRoute(item.getDepAddress() + Constants.STRIKETHROUGH + item.getArrAddress());
            carOrder.setOrderId(item.getOrderId());
            carOrder.setPayWay(PayWayEnum.getEnum(item.getPayWay()).getMsg());
            carOrder.setOrderPrice(item.getOrderPrice());
            carOrder.setRideNum(String.valueOf(item.getRideNum()));
            carOrder.setContactsInfo(item.getContactsUser() + Constants.STRIKETHROUGH + item.getContactsPhone());
            carOrder.setPayPrice(item.getPayPrice());
            carOrder.setPayTime(item.getPayTime());
            carOrder.setPayNo(item.getPayNo());
            ProductCar productCar = productCarService.findById(item.getProductCarId());
            carOrder.setPerSePrice(productCar.getSupperFinPrice());
            carOrder.setTotalSePrice(carOrder.getPerSePrice().multiply(new BigDecimal(carOrder.getRideNum())));
            carOrder.setAdminCommission(item.getFarePrice());
            carOrder.setMarketPrice(productCar.getSalePrice());
            return carOrder;
        }).collect(Collectors.toList());

        return carOrders;
    }


    @Override
    public List<DisCarOrder> queryOrderDistributor(OrderDetailQuery orderDetailQuery) {
        logger.info("分销商查询订单列表 req:{}", JsonUtils.toJson(orderDetailQuery));
        if (orderDetailQuery == null) {
            return Lists.newArrayList();
        }
        PageHelper.startPage(orderDetailQuery.getPageNo(), orderDetailQuery.getPageSize());
        Condition condition = new Condition(OrderDetail.class);
        Example.Criteria criteria = condition.createCriteria();
        buildCondition(criteria, orderDetailQuery);
        PageHelper.startPage(orderDetailQuery.getPageNo(), orderDetailQuery.getPageSize());
        List<OrderDetail> list = findByCondition(condition);
        List<DisCarOrder> result = list.stream().map(item->{
            DisCarOrder disCarOrder = new DisCarOrder();
            disCarOrder.setProductTypeName(TypeEnum.getEnum(item.getType()).msg);
            disCarOrder.setUserNme(item.getUserName());
            disCarOrder.setOrderStatus(Integer.valueOf(item.getStatus()));
            disCarOrder.setOrderTime(item.getOrderTime());
            disCarOrder.setCityName(item.getOrderCity());
            disCarOrder.setServiceType(ServiceTypeEnum.getEnum(String.valueOf(item.getOrderType())).msg);
            disCarOrder.setOrderRoute(item.getDepAddress() + Constants.STRIKETHROUGH + item.getArrAddress());
            disCarOrder.setOrderId(item.getOrderId());
            disCarOrder.setPayWay(PayWayEnum.getEnum(item.getPayWay()).getMsg());
            disCarOrder.setOrderPrice(item.getOrderPrice());
            disCarOrder.setRideNum(String.valueOf(item.getRideNum()));
            disCarOrder.setContactsInfo(item.getContactsUser() + Constants.STRIKETHROUGH + item.getContactsPhone());
            disCarOrder.setPayPrice(item.getPayPrice());
            disCarOrder.setPayTime(item.getPayTime());
            disCarOrder.setPayNo(item.getPayNo());
            ProductCar productCar = productCarService.findById(item.getProductCarId());
            disCarOrder.setDisPerPrice(productCar.getDistorFinPrice());
            disCarOrder.setDisPerPrice(productCar.getDistorFinPrice().multiply(new BigDecimal(disCarOrder.getRideNum())));
            return disCarOrder;
        }).collect(Collectors.toList());
        return result;
    }

    @Override
    public List<CarOrder> queryOrderSupplier(OrderDetailQuery orderDetailQuery) {
        logger.info("分销商查询订单列表 req:{}", JsonUtils.toJson(orderDetailQuery));
        if (orderDetailQuery == null) {
            return Lists.newArrayList();
        }
        PageHelper.startPage(orderDetailQuery.getPageNo(), orderDetailQuery.getPageSize());
        Condition condition = new Condition(OrderDetail.class);
        Example.Criteria criteria = condition.createCriteria();
        buildCondition(criteria, orderDetailQuery);
        PageHelper.startPage(orderDetailQuery.getPageNo(), orderDetailQuery.getPageSize());
        List<OrderDetail> list = findByCondition(condition);
        List<CarOrder> result = list.stream().map(item->{
            CarOrder carOrder = new CarOrder();
            carOrder.setProductTypeName(TypeEnum.getEnum(item.getType()).msg);
            carOrder.setUserNme(item.getUserName());
            carOrder.setOrderStatus(Integer.valueOf(item.getStatus()));
            carOrder.setOrderTime(item.getOrderTime());
            carOrder.setCityName(item.getOrderCity());
            carOrder.setServiceType(ServiceTypeEnum.getEnum(String.valueOf(item.getOrderType())).msg);
            carOrder.setOrderRoute(item.getDepAddress() + Constants.STRIKETHROUGH + item.getArrAddress());
            carOrder.setOrderId(item.getOrderId());
            carOrder.setPayWay(PayWayEnum.getEnum(item.getPayWay()).getMsg());
            carOrder.setOrderPrice(item.getOrderPrice());
            carOrder.setRideNum(String.valueOf(item.getRideNum()));
            carOrder.setContactsInfo(item.getContactsUser() + Constants.STRIKETHROUGH + item.getContactsPhone());
            carOrder.setPayPrice(item.getPayPrice());
            carOrder.setPayTime(item.getPayTime());
            carOrder.setPayNo(item.getPayNo());
            return carOrder;
        }).collect(Collectors.toList());
        return result;
    }

    @Override
    public Result<CreateOrderResponse> createOrder(CreateOrderRequest createOrderRequest) {
        try {
            if (DateUtils.addHours(new Date(), Constants.ADVANCE_HOUR).after(createOrderRequest.getUseTime())) {
                logger.info("用车时间必须在当前时间的" + Constants.ADVANCE_HOUR + "小时之后");
                return ResultGenerator.genFailResult("用车时间必须在当前时间的" + Constants.ADVANCE_HOUR + "小时之后");
            }
            OrderDetail orderDetail = new OrderDetail();
            PriceStrategy priceStrategie = priceStrategyService.findBy("bizType",orderDetail.getOrderType());
            if (priceStrategie == null) {
                orderDetail.setFarePrice(BigDecimal.ZERO);
            } else {
                orderDetail.setFarePrice(createOrderRequest.getOrderPrice().multiply(priceStrategie.getAddPercent()));
            }

            orderDetail.setPid(createOrderRequest.getProductId());
            orderDetail.setOrderId(OrderIdUtils.getOrderId());
            orderDetail.setOrderType(Byte.valueOf(ServiceTypeEnum.getEnum(createOrderRequest.getServiceType()).type));
            orderDetail.setProductType(ProductTypeEnum.CAR.type);
            orderDetail.setOrderCity(createOrderRequest.getCityName());
            orderDetail.setStatus(OrderStatusEnum.INIT.getCode());
            orderDetail.setOrderTime(new Date());
            orderDetail.setOrderPrice(createOrderRequest.getOrderPrice());
            orderDetail.setPayPrice(createOrderRequest.getPayPrice());
            orderDetail.setDiscountPrice(createOrderRequest.getDisPrice());
            orderDetail.setPayWay(PayWayEnum.getEnum(Byte.valueOf(createOrderRequest.getPayWay())).getCode());
            orderDetail.setUserType(createOrderRequest.getUserType());
            orderDetail.setUserName(createOrderRequest.getUserName());
            orderDetail.setUserTime(createOrderRequest.getUseTime());
            orderDetail.setContactsUser(createOrderRequest.getContactsUser());
            orderDetail.setContactsPhone(createOrderRequest.getContactsPhone());
            orderDetail.setDepAddress(createOrderRequest.getDepPlace());
            orderDetail.setArrAddress(createOrderRequest.getArrPlace());
            orderDetail.setRideNum(createOrderRequest.getRideNum());
            orderDetail.setCityId(Integer.valueOf(createOrderRequest.getCityId()));
            orderDetail.setType(createOrderRequest.getType());
            orderDetail.setProductCarId(createOrderRequest.getCarModelId());

            // TODO: 2017/10/5  订单如何与供应商关联
            save(orderDetail);
            OrderDynamicDetail orderDynamicDetail = new OrderDynamicDetail();
            orderDynamicDetail.setOrderDesc(Constants.PAIED_MSG);
            orderDynamicDetail.setChecked((byte) 0);
            orderDynamicDetail.setOrderId(orderDetail.getOrderId());
            OrderDynamicDetail orderDynamicDetail1 = new OrderDynamicDetail();
            orderDynamicDetail1.setOrderDesc(Constants.READY_MSG);
            orderDynamicDetail1.setChecked((byte) 0);
            orderDynamicDetail1.setOrderId(orderDetail.getOrderId());
            orderDynamicDetailService.save(Lists.newArrayList(orderDynamicDetail,orderDynamicDetail1));
            return ResultGenerator.genSuccessResult(buildResponse(orderDetail,orderDynamicDetail1));
        } catch (Exception e) {
            logger.error("生单发生异常,req:{}", JsonUtils.toJson(createOrderRequest), e);
            return ResultGenerator.genFailResult("生单发生异常");
        }
    }

    private CreateOrderResponse buildResponse(OrderDetail orderDetail,OrderDynamicDetail orderDynamicDetail1) {
        CreateOrderResponse createOrderResponse = new CreateOrderResponse();
        createOrderResponse.setOrderDynamicDetails(Lists.newArrayList(orderDynamicDetail1));
        createOrderResponse.setContactsInfo(orderDetail.getContactsPhone());
        createOrderResponse.setOrderId(orderDetail.getOrderId());
        List<PayInfo> payInfos = Lists.newArrayList(
                new PayInfo.Builder().setPayPrice(orderDetail.getPayPrice()).setPayWay(orderDetail.getPayWay()).build(),
                new PayInfo.Builder().setPayPrice(orderDetail.getDiscountPrice()).setPayWay(PayWayEnum.COUPON.getCode()).build()
                );
        createOrderResponse.setPayInfo(payInfos);
        return createOrderResponse;
    }


    private void buildCondition(Example.Criteria criteria, OrderDetailQuery orderDetailQuery) {
        if (StringUtils.isNotEmpty(orderDetailQuery.getType())) {
            criteria.andEqualTo("type", orderDetailQuery.getType());
        }
        if (StringUtils.isNotEmpty(orderDetailQuery.getOrderSource())) {
            criteria.andEqualTo("orderSource", orderDetailQuery.getOrderSource());
        }
        if (StringUtils.isNotEmpty(orderDetailQuery.getSupplierName())) {
            criteria.andEqualTo("supplierName", orderDetailQuery.getSupplierName());
        }
        if (orderDetailQuery.getOrderStatus() != null) {
            criteria.andEqualTo("status", orderDetailQuery.getOrderStatus());
        }
        if (orderDetailQuery.getReqBeginDate() !=  null) {
            criteria.andGreaterThanOrEqualTo("orderTime", orderDetailQuery.getReqBeginDate());
        }
        if (orderDetailQuery.getReqEndDate() != null) {
            criteria.andLessThanOrEqualTo("orderTime", orderDetailQuery.getReqEndDate());
        }
    }
}
